/**
 * @description: RouteRecordRaw 参数说明
 * @param: path {string} 跳转路径
 * @param: redirect {string} 重定向跳转路径
 * @param: component {string} 组件
 * @param: meta {object} 可以自定义一些内容
 *         icon {string} 菜单对应的图标icon, 推荐使用svg形式
 *         title {string} 菜单对应的标题，也作为浏览器标签标题展示
 *         authCodes {array} 用户权限code
 *         isBlank {boolean} 默认false， 是否需要在浏览器新标签页中打开
 *
 *         setBreadcrumbs {function} 重置面包屑内容
 *         iframeSrc {string} 页面内嵌iframe的地址，注册路由时请使用 @/layouts/iframe/index.vue
 *         isPageReused {boolean} 默认false 如果两个路由使用同一个组件，一定要设置isPageReused: true
 *         keepAlive {boolean} 默认false，页面是否被缓，true为缓存页面
 * @return void {*}
 */
import { createRouter, createWebHistory } from 'vue-router';

import { homeRoutes } from './modules/home';
import { meterReadingRoutes } from './modules/meter-reading';

import type { RouteRecordRaw, RouteLocationNormalized } from 'vue-router';

import Layout from '@/layouts/index.vue';
import Redirect from '@/layouts/redirect/index.vue';
import { useAppStore } from '@/store/app';
import { usePermissionStore } from '@/store/permission';
import { useUserStore } from '@/store/user';
import Page401 from '@/views/401.vue';
import Page404 from '@/views/404.vue';

const excludePath = [
  '/error',
  '/error/401',
  '/error/404'
];

const viteProjectRoot = import.meta.env.VITE_APP_ROOT;
let appStore: TypeObject;
let userStore: TypeObject;
let permissionStore: TypeObject;

export const constantRoutes: Array<RouteRecordRaw> = [];

export const catchAllRoutes: Array<RouteRecordRaw> = [
  {
    path: '/redirect',
    component: Layout,
    name: 'redirect',
    meta: {
      hidden: true,
    },
    children: [
      {
        path: '/redirect/:catchAll(.*)',
        component: Redirect,
      }
    ],
  },
  {
    path: '/error',
    name: 'error',
    component: Layout,
    redirect: '/error/404',
    meta: {
      hidden: true,
    },
    children: [
      {
        path: '/error/404',
        name: '404',
        component: Page404,
        meta: {
          hidden: true,
        },
      },
      {
        path: '/error/401',
        name: '401',
        component: Page401,
        meta: {
          hidden: true,
          hideFooter: true,
        },
      }
    ],
  }
];

export const asyncRoutes: Array<RouteRecordRaw> = [
  ...homeRoutes,
  ...meterReadingRoutes,
];

const router = createRouter({
  history: createWebHistory(viteProjectRoot),
  routes: [...constantRoutes, ...catchAllRoutes],
  scrollBehavior: () => ({
    left: 0,
    top: 0,
  }),
});

router.beforeEach(async (to: RouteLocationNormalized, from: RouteLocationNormalized, next: Func) => {
  if (!appStore) {
    appStore = useAppStore();
  }
  if (!userStore) {
    userStore = useUserStore();
  }
  if (!permissionStore) {
    permissionStore = usePermissionStore();
  }

  // 需要根据条件动态设置面包屑的时候可以在meta中设置setBreadcrumbs函数
  if (typeof to.meta.setBreadcrumbs === 'function') {
    to.meta.breadcrumbs = to.meta.setBreadcrumbs(to);
  }
  // 使用同一个页面组件的不同路由
  const isPageReused = from.meta.isPageReused && to.meta.isPageReused;

  const hasMenus = userStore.authKeys && userStore.authKeys.length > 0;
  if (hasMenus) {
    if (isPageReused) {
      next(`/redirect${to.fullPath}`);
    } else {
      next();
    }
  } else {
    const { authKeys } = await userStore.getUserInfo();
    const { accessedRoutes, permissionRoutes } = await permissionStore.generateRoutes(authKeys);
    console.log('根据用户权限动态生成的路由:', accessedRoutes);

    //  设置用户输入 / 跳转至有权限的第一个路由
    const firstRoute = permissionRoutes.filter(
      (item: RouteRecordRaw) => !excludePath.includes(item.path) && item.meta
    )[0];

    if (firstRoute) {
      accessedRoutes.unshift({
        path: '/',
        redirect: firstRoute.path,
        meta: {
          hidden: true,
        },
      });
    }
    // 动态添加路由
    accessedRoutes.forEach((item: any) => {
      router.addRoute(item);
    });

    // 配置404
    router.addRoute({
      path: '/:catchAll(.*)',
      redirect: '/error/404',
      meta: {
        hidden: true,
      },
    });

    // 用户没有菜单权限 进入401 用户无权限页面
    if (!authKeys.length) {
      if (excludePath.includes(to.path)) {
        next();
        return;
      }
      next('/error/401');
      return;
    }

    next({ ...to, replace: true });
  }
});

router.afterEach((to: RouteLocationNormalized) => {
  setTimeout(() => {
    const baseTitle = import.meta.env.VITE_APP_NAME_ZH;
    window.document.title = to.meta.title ? `${to.meta.title} | ${baseTitle}` : baseTitle;
  }, 0);
});

export default router;
